package edu.drexel.cs544.group11.serverpersistence;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import edu.drexel.cs544.group11.common.Product;

/**
 * Persists product information to a data store.
 * 
 * CS 544
 * 
 * @author Group 11:
 * @author Jason Setzer
 * @author Tam Thongsima
 * @author Kenny Oyefara
 * @author Chase Miller
 * 
 * @date Spring 2013
 * 
 */
public class ProductPersistence {
    private String filelocation;
    
    public ProductPersistence(String fileLocation) {
	this.filelocation = fileLocation;
    }
    
    /**
     * This function retrieve product information from inventory XML file. For
     * admin and customers Assumes that the user has already been validated by
     * the server
     * 
     * @param Barcode
     * @return Product information string or error message
     */
    public Product ReadFromBarcode(String Barcode) {
	try {
	    
	    File fXmlFile = new File(filelocation);
	    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
	    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
	    Document doc = docBuilder.parse(fXmlFile);
	    
	    doc.getDocumentElement().normalize();
	    
	    NodeList nList = doc.getElementsByTagName("product");
	    
	    for (int temp = 0; temp < nList.getLength(); temp++) {
		
		Node nNode = nList.item(temp);
		
		if (nNode.getNodeType() == Node.ELEMENT_NODE) {
		    
		    Element eElement = (Element) nNode;
		    String compareElement = eElement.getElementsByTagName("barcode").item(0).getTextContent();
		    if (compareElement.equals(Barcode)) {
			Product product = new Product(eElement.getElementsByTagName("barcode").item(0).getTextContent());
			product.setItemName(eElement.getElementsByTagName("name").item(0).getTextContent());
			product.setPrice(Double.parseDouble(eElement.getElementsByTagName("price").item(0).getTextContent()));
			product.setQuantity(Integer.parseInt(eElement.getElementsByTagName("quantity").item(0).getTextContent()));
			product.setCategory(eElement.getElementsByTagName("category").item(0).getTextContent());
			return product;
		    }
		}
	    }
	    return null;
	}
	catch (Exception e) {
	    e.printStackTrace();
	    return null;
	}
    }
    
    /**
     * This function make update on the product information in XML file. For
     * admin Assumes that the user has already been validated by the server Must
     * know element tag name before call.
     * 
     * @param barcode
     * @param changeElement
     * @param changeValue
     * @return confirmation message or error message.
     */
    public boolean UpdateProductElement(String barcode, String changeElement, String changeValue) {
	
	try {
	    File fXmlFile = new File(filelocation);
	    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
	    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
	    Document doc = docBuilder.parse(fXmlFile);
	    
	    doc.getDocumentElement().normalize();
	    
	    NodeList nList = doc.getElementsByTagName("product");
	    
	    for (int temp = 0; temp < nList.getLength(); temp++) {
		
		Node nNode = nList.item(temp);
		
		if (nNode.getNodeType() == Node.ELEMENT_NODE) {
		    
		    Element eElement = (Element) nNode;
		    String compareElement = eElement.getElementsByTagName("barcode").item(0).getTextContent();
		    if (compareElement.equals(barcode)) {
			eElement.getElementsByTagName(changeElement).item(0).setTextContent(changeValue);
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			DOMSource source = new DOMSource(doc);
			StreamResult result = new StreamResult(new File(filelocation));
			transformer.transform(source, result);
			return true;
		    }
		}
	    }
	    return false;
	}
	catch (Exception e) {
	    e.printStackTrace();
	    return false;
	}
    }
    
    /**
     * This function add new product into the inventory XML file. For admin
     * Assumes that the user has already been validated by the server
     * 
     * @param barcode
     * @param category
     * @param name
     * @param price
     * @param quantity
     * @return Confirmation message or error message
     */
    public boolean AddProductElement(String barcode, String category, String name, double price, int quantity) {
	try {
	    
	    File fXmlFile = new File(filelocation);
	    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
	    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
	    Document doc = docBuilder.parse(fXmlFile);
	    
	    Node company = doc.getFirstChild();
	    Element product = doc.createElement("product");
	    
	    Element barcodeE = doc.createElement("barcode");
	    Element categoryE = doc.createElement("category");
	    Element nameE = doc.createElement("name");
	    Element priceE = doc.createElement("price");
	    Element quantityE = doc.createElement("quanity");
	    
	    barcodeE.appendChild(doc.createTextNode(barcode));
	    categoryE.appendChild(doc.createTextNode(category));
	    nameE.appendChild(doc.createTextNode(name));
	    priceE.appendChild(doc.createTextNode(String.valueOf(price))); //String.valueOf(double price)
	    quantityE.appendChild(doc.createTextNode(String.valueOf(quantity)));
	    
	    product.appendChild(barcodeE);
	    product.appendChild(categoryE);
	    product.appendChild(nameE);
	    product.appendChild(priceE);
	    product.appendChild(quantityE);
	    
	    company.appendChild(product);
	    
	    TransformerFactory transformerFactory = TransformerFactory.newInstance();
	    Transformer transformer = transformerFactory.newTransformer();
	    DOMSource source = new DOMSource(doc);
	    StreamResult result = new StreamResult(new File(filelocation));
	    transformer.transform(source, result);
	}
	catch (Exception e) {
	    e.printStackTrace();
	    return false;
	}
	
	return true;
    }
}
